
/*
 * ClientMain.java
 * 客户端的入口函数
 */
import java.net.*;
import java.io.*;
import java.util.*;

public class ClientMain {
    static final String SERVER_ADDR = "localhost";
    
    public static void main(String[] args)
    {
        Global.print_copyright("客户端");
        try (Socket soc = new Socket(SERVER_ADDR, Global.SERVER_PORT);
                Scanner scn = new Scanner(System.in);
                
                // 只和服务器工作线程的 ObjectInputStream 对应，都只 new 一次
                ObjectOutputStream os = new ObjectOutputStream(soc.getOutputStream());) {
            
            System.out.printf("已连接到服务器 %s:%d。\n", SERVER_ADDR, Global.SERVER_PORT);
            
            /* 输入名字 */
            String name = null;
            while (true) {
                name = get_name(scn);
                os.writeObject(name); // 这里必须和服务器工作线程一致！
                
                ObjectInputStream is = new ObjectInputStream(soc.getInputStream());
                Stat s = (Stat)is.readObject();
                
                if (s == Stat.OK) {
                    System.out.println(s);
                    break;
                } else {
                    System.err.println(s);
                }
            }
            
            /* 创建接收线程 */
            new Thread() {
                @Override
                public void run()
                {
                    try {
                        while (true) {
                            ObjectInputStream is = new ObjectInputStream(soc.getInputStream());
                            System.out.println(is.readObject());
                        }
                    } catch (IOException ex) {
                        if (!soc.isClosed()) {
                            ex.printStackTrace();
                        }
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            
            /* 处理用户输入，向服务器发送消息 */
            while (!soc.isClosed()) {
                System.out.print("> ");
                String cmd = scn.nextLine();
                Object parsed = Parser.parse(cmd);
                if (parsed == null) {
                    System.err.println("命令格式错误，请重新输入！");
                    continue;
                }
                if (parsed instanceof BroadcastMsg) {
                    ((BroadcastMsg)parsed).set_sender(name);
                } else if (parsed instanceof PrivateMsg) {
                    ((PrivateMsg)parsed).set_sender(name);
                }
                os.writeObject(parsed);
                if (parsed instanceof End) {
                    soc.close();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }        
    }
    
    /**
     * 提示用户输入名字，用户输入后，去除首尾空白<br/>
     * 如果里面有（半角）双引号，或者为空，则要求重新输入
     * 
     * @param scn 由主调函数负责关闭
     * @return 保证不为 null
     */
    static String get_name(Scanner scn)
    {
        String name = null;
        while (true) {
            System.out.print("请输入你的名字，不能有引号，按回车键提交> ");
            name = scn.nextLine().trim();
            
            if (name.length() == 0) {
                System.err.println("名字为空，请重新输入！");
                continue;
            }
            if (name.indexOf('\"') != -1) {
                System.err.println("名字中不允许有（半角）双引号，请重新输入！");
                continue;
            }
            break;
        }
        return name;
    }
}